package com.guaika.reggie.filter;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.guaika.reggie.common.BaseContext;
import com.guaika.reggie.common.ResultMessage;
import com.guaika.reggie.common.StringChars;
import com.guaika.reggie.entity.Permissions;
import com.guaika.reggie.mapper.PermissionsMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * @author GuaiKa
 */
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
@Slf4j
@Component
public class LoginCheckFilter implements Filter {
    @Autowired
    private PermissionsMapper permissionsMapper;

    public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest)request;

        HttpServletResponse httpServletResponse = (HttpServletResponse)response;
        String requestUrl = httpServletRequest.getRequestURI();
        String[] filterUrls = new String[]{
                "/employee/login",
                "/employee/logout",
                "/backend/**",
                "/front/**",
                "/user/sendMsg",
                "/user/login",
                "/doc.html",
                "/webjars/**",
                "/swagger-resources",
                "/v2/api-docs",
                "/permissions/allPermissions"
        };
        //如果此次请求路径不在拦截范围内，则放行
        if(checkUrl(filterUrls,requestUrl)){
            log.info("此次请求无需处理：{}",requestUrl);
            chain.doFilter(httpServletRequest,httpServletResponse);
            return;
        }
        //如果有登录session缓存，则放行
        if(httpServletRequest.getSession().getAttribute(StringChars.EMPLOYEE.getStr())!=null){
            //获取当前登录用户id
            Long id = (Long) httpServletRequest.getSession().getAttribute(StringChars.EMPLOYEE.getStr());
            //权限过滤
            List<String> permissions = permissionsMapper.permissionsListById(id);
            //判断是否有对应路径权限
            String reqMethodAndPath = httpServletRequest.getMethod()+" " + requestUrl;
            if(!permissions.contains(reqMethodAndPath) && id !=1){
                response.getWriter().write(JSON.toJSONString(ResultMessage.error(StringChars.NO_PERMISSION.getStr())));
                return;
            }
            log.info("当前用户id为：{}",id);
            //将id存入线程内
            BaseContext.set(id);
            //放行当前请求
            chain.doFilter(httpServletRequest,httpServletResponse);
            return;
        }
        //如果有登录session缓存，则放行
        if(httpServletRequest.getSession().getAttribute(StringChars.User.getStr())!=null){
            //获取当前登录用户id
            Long id = (Long) httpServletRequest.getSession().getAttribute(StringChars.User.getStr());
            log.info("当前用户id为：{}",id);
            //将id存入线程内
            BaseContext.set(id);
            //放行当前请求
            chain.doFilter(httpServletRequest,httpServletResponse);
            return;
        }
        //如果未登录则拦截
        response.getWriter().write(JSON.toJSONString(ResultMessage.error(StringChars.NOTLOGIN.getStr())));
        return;
    }

    /***
     * 检查url是否在拦截范围内
     * @param filterUrls
     * @param url
     * @return
     */
    public boolean checkUrl(String[] filterUrls ,String url){
        for(String urls:filterUrls){
            //通配符匹配路径
            boolean match = PATH_MATCHER.match(urls, url);
            if(match){
                return true;
            }
        }
        return false;
    }
}
